package utils

import (
	"crypto/md5"
	"database/sql"
	"errors"
	"fmt"
	"github.com/astaxie/beego"
	_ "github.com/go-sql-driver/mysql"
	"golang.org/x/crypto/bcrypt"
	"golang.org/x/crypto/scrypt"
	"log"
)

const (
	SecretKEY              string = "JWT-Secret-Key"
	PasswordHashBytes             = 16
)

var db *sql.DB

func InitMysql()  {
	fmt.Println("InitMysql...")
	driverName := beego.AppConfig.String("driverName")

	//数据库连接
	user 	:= beego.AppConfig.String("mysqluser")
	pwd  	:= beego.AppConfig.String("mysqlpass")
	host  	:= beego.AppConfig.String("mysqlurls")
	port  	:= beego.AppConfig.String("mysqlport")
	dbname  := beego.AppConfig.String("mysqldb")

	dbConn := user + ":" + pwd + "@tcp(" + host + ":" + port + ")/" + dbname + "?charset=utf8"

	db1, err := sql.Open(driverName, dbConn)
	if err != nil {
		fmt.Println(err.Error())
	}else{
		db = db1
		CreateTableWithUser()
	}
}

func ModifyDB(sql string, args ...interface{}) (int64, error) {
	result, err := db.Exec(sql, args...)
	if err != nil {
		log.Println(err)
		return 0, err
	}
	count, err := result.RowsAffected()
	if err != nil {
		log.Println(err)
		return 0, err
	}
	return count, nil
}

//创建用户表
func CreateTableWithUser()  {
	sql := `CREATE TABLE IF NOT EXISTS users(
	id INT(4) PRIMARY KEY AUTO_INCREMENT NOT NULL,
	username VARCHAR(64),
	password VARCHAR(64),
	status INT(4),
	createtime INT(10)
);`
	ModifyDB(sql)
}

//查询
func QueryRowDB(sql string) *sql.Row  {
	return db.QueryRow(sql)
}

func MD5(str string) string  {
	md5str := fmt.Sprintln("%x", md5.Sum([]byte(str)))
	return md5str
}

func GeneratePassHash(password string, salt string) (hash string, err error) {
	h, err := scrypt.Key([]byte(password), []byte(salt), 16384, 8, 1, PasswordHashBytes)
	if err != nil {
		return "", errors.New("error: failed to generate password hash")
	}

	return fmt.Sprintf("%x", h), nil
}

func PasswordCrypt(password string) (string, error){
	hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
	if err != nil {
		return "", err
	}
	return string(hash), err
}

func VerifyCryptPwd(password string, loginPwd string) bool  {
	err := bcrypt.CompareHashAndPassword([]byte(password), []byte(loginPwd)) //验证（对比）
	if err != nil {
		return false
	} else {
		return true
	}
}
